<template>
  <Tooltip
    v-if="isSHowToolTip"
    transfer
    placement="top"
    :content="`${percent}%`"
  >
    <div :style="circleSize" :class="wrapClasses">
      <svg viewBox="0 0 100 100">
        <defs v-if="showDefs">
          <linearGradient :id="id" x1="100%" y1="0%" x2="0%" y2="0%">
            <stop offset="0%" :stop-color="strokeColor[0]"></stop>
            <stop offset="100%" :stop-color="strokeColor[1]"></stop>
          </linearGradient>
        </defs>
        <path :d="pathString" :stroke="trailColor" :stroke-width="trailWidth" :fill-opacity="0" :style="trailStyle" :stroke-linecap="strokeLinecap" />
        <path :d="pathString" :stroke-linecap="strokeLinecap" :stroke="strokeValue" :stroke-width="computedStrokeWidth" fill-opacity="0" :style="pathStyle" />
      </svg>
    </div>
  </Tooltip>
  <div
    v-else
    :style="circleSize"
    :class="wrapClasses">
    <svg viewBox="0 0 100 100">
      <defs v-if="showDefs">
        <linearGradient :id="id" x1="100%" y1="0%" x2="0%" y2="0%">
          <stop offset="0%" :stop-color="strokeColor[0]"></stop>
          <stop offset="100%" :stop-color="strokeColor[1]"></stop>
        </linearGradient>
      </defs>
      <path :d="pathString" :stroke="trailColor" :stroke-width="trailWidth" :fill-opacity="0" :style="trailStyle" :stroke-linecap="strokeLinecap" />
      <path :d="pathString" :stroke-linecap="strokeLinecap" :stroke="strokeValue" :stroke-width="computedStrokeWidth" fill-opacity="0" :style="pathStyle" />
    </svg>
    <div :class="innerClasses">
      <slot></slot>
    </div>
  </div>
</template>
<script setup>
import { ref, defineProps,toRefs,computed } from 'vue'
import { oneOf } from '../../utils/assist';
import random from '../../utils/random_str';
import Tooltip from '../tooltip/tooltip-v2.vue';

const prefixCls = 'haloe-circle';

const props = defineProps({
  percent: {
    type: Number,
    default: 0,
    validator: (val) => val >= 0 && val <= 100
  },
  size: {
    type: Number,
    default: 120
  },
  strokeWidth: {
    type: Number,
    default: 6
  },
  strokeColor: { // 进度环的颜色，支持传入数组，显示为渐变色
    type: [String, Array],
    default: '#2d8cf0'
  },
  strokeLinecap: { // 进度环顶端的形状，可选值为square（方）和round（圆）
    validator (value) {
      return oneOf(value, ['square', 'round']);
    },
    default: 'round'
  },
  trailWidth: { // 进度环的线宽，单位 px
    type: Number,
    default: 5
  },
  trailColor: { // 进度环背景的线宽，单位 px
    type: String,
    default: '#eaeef2'
  },
  dashboard: { // 是否显示为仪表盘
    type: Boolean,
    default: false
  }
})
const id = ref(`${prefixCls}-${random(3)}`)

const {size, percent,dashboard,strokeColor, strokeWidth} = toRefs(props)
const isSHowToolTip = computed(() => {
  return size.value <= 20
})
const circleSize = computed(() => {
  return {
    width: `${size.value}px`,
    height: `${size.value}px`
  }
})
const computedStrokeWidth = computed(() => {
  return percent.value === 0 && dashboard.value ? 0 : strokeWidth.value
})
const radius = computed(() => {
  return 50 - strokeWidth.value / 2
})
const pathString = computed(() => {
  if (dashboard.value) {
    return `M 50,50 m 0,${radius.value}
                    a ${radius.value},${radius.value} 0 1 1 0,-${2 * radius.value}
                    a ${radius.value},${radius.value} 0 1 1 0,${2 * radius.value}`
  } else {
    return `M 50,50 m 0,-${radius.value}
                    a ${radius.value},${radius.value} 0 1 1 0,${2 * radius.value}
                    a ${radius.value},${radius.value} 0 1 1 0,-${2 * radius.value}`
  }
})
const len = computed(() => {
  return Math.PI * 2 * radius.value
})
const trailStyle = computed(() => {
  let style = {};
  if (dashboard.value) {
    style = {
      'stroke-dasharray': `${len.value - 75}px ${len.value}px`,
      'stroke-dashoffset': `-${75 / 2}px`,
      'transition': 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s'
    };
  }
  return style
})
const pathStyle = computed(() => {
  let style = {};
  if (dashboard.value) {
    style = {
      'stroke-dasharray': `${(percent.value / 100) * (len.value - 75)}px ${len.value}px`,
      'stroke-dashoffset': `-${75 / 2}px`,
      'transition': 'stroke-dashoffset .3s ease 0s, stroke-dasharray .6s ease 0s, stroke .6s, stroke-width .06s ease .6s'
    };
  } else {
    style = {
      'stroke-dasharray': `${len.value}px ${len.value}px`,
      'stroke-dashoffset': `${((100 - percent.value) / 100 * len.value)}px`,
      'transition': 'stroke-dashoffset 0.6s ease 0s, stroke 0.6s ease'
    };
  }
  return style
})
const wrapClasses = computed(() => {
  return `${prefixCls}`
})
const innerClasses = computed(() => {
  return `${prefixCls}-inner`
})
const strokeValue = computed(() => {
  let color = strokeColor.value
  if (typeof strokeColor.value !== 'string') {
    color = `url(#${id.value})`
  }
  return color
})
const showDefs = computed(() => {
  return typeof strokeColor.value !== 'string'
})
</script>
